package iris_controller

import (
	"fmt"
	"github.com/kataras/iris/v12"
	"gluenet/modules/manager/server/domain"
	"gluenet/modules/manager/server/domain/vo"
	"gluenet/modules/manager/server/infra"
	"gluenet/modules/manager/server/infra/prepare"
)

func init() {
	prepare.RegisterAuthController(func() {
		controller := NewInstanceController()
		prepare.InjectAuthController(func() *Instance {
			return controller
		})
	})
}

type Instance struct {
	Instance *domain.Instance
}

func NewInstanceController() *Instance {
	r := &Instance{}
	prepare.FetchDependency(&r.Instance)
	return r
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/instance/all
func (c *Instance) GetAll(ctx iris.Context) *infra.Response {
	id := ctx.Values().GetString("user_id")
	admin, err := ctx.Values().GetBool("admin")
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	objs, err := c.Instance.FindByUser(admin, id, map[string]interface{}{})

	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(objs)
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/instance/query
func (c *Instance) GetQuery(ctx iris.Context) *infra.Response {
	params := ctx.URLParams()
	var query = map[string]interface{}{}
	for k, v := range params {
		query[k] = v
	}

	id := ctx.Values().GetString("user_id")
	admin, err := ctx.Values().GetBool("admin")
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}

	cfg, err := c.Instance.FindByUser(admin, id, query)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(cfg)
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/instance/all/runtime/list
func (c *Instance) GetAllRuntimeList(ctx iris.Context) *infra.Response {
	id := ctx.Values().GetString("user_id")
	admin, err := ctx.Values().GetBool("admin")
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}

	objs, err := c.Instance.FindRuntimeListBy(admin, id, map[string]interface{}{})
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(objs)
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/instance/all/runtime
func (c *Instance) GetAllRuntime(ctx iris.Context) *infra.Response {
	id := ctx.Values().GetString("user_id")
	admin, err := ctx.Values().GetBool("admin")
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}

	objs, err := c.Instance.FindRuntimeBy(admin, id, map[string]interface{}{})
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(objs)
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/instance/getlinks
func (c *Instance) GetGetlinks(ctx iris.Context) *infra.Response {
	guid := ctx.URLParam("guid")
	user_id := ctx.Values().GetString("user_id")
	cfg, err := c.Instance.GetLinks(guid, user_id)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(cfg)
}

// Get serves
// Method:   POST
// Resource: http://localhost:8080/apis/instance/setlinks
func (c *Instance) PostSetlinks(ctx iris.Context) *infra.Response {
	var links struct {
		StrategyGuid string   `json:"strategy_guid"`
		AppsGuid     []string `json:"application_guids"`
	}
	ctx.ReadJSON(&links)
	user_id := ctx.Values().GetString("user_id")

	if err := c.Instance.DeleteAllLinks(links.StrategyGuid); err != nil {
		return infra.ResponseReqErr(err, nil)
	}

	var linkRes = [][2]interface{}{}
	for _, app := range links.AppsGuid {
		state := true
		link, err := c.Instance.CreateLinks(links.StrategyGuid, app, user_id)
		if err != nil {
			state = false
		}
		linkRes = append(linkRes, [2]interface{}{link, state})
	}

	res, err := c.Instance.InfoStrategy(links.StrategyGuid, links.AppsGuid, user_id)
	if err != nil {
		return infra.ResponseReqErr(fmt.Errorf("info strategy %v", err), nil)
	} else {
		fmt.Printf("\n info succeed %v \n", res)
	}

	return infra.ResponseOK(linkRes)
}

// Create serves
// Method:   POST
// Resource: http://localhost:8080/apis/instance/create
func (c *Instance) PostCreate(ctx iris.Context) *infra.Response {
	id := ctx.Values().GetString("user_id")
	req := vo.CreateInstanceReq{}
	if err := ctx.ReadJSON(&req); err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	req.UserID = id
	ins, err := c.Instance.Create(req)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(ins)
}

// Create serves
// Method:   DELETE
// Resource: http://localhost:8080/apis/instance/del
func (c *Instance) DeleteDel(ctx iris.Context) *infra.Response {
	guid := ctx.URLParam("guid")
	userId := ctx.Values().GetString("user_id")
	_, err := c.Instance.Remove(guid, userId)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(nil)
}

// Create serves
// Method:   GET
// Resource: http://localhost:8080/apis/instance/dag/jaeger
func (c *Instance) GetDagJaeger(ctx iris.Context) *infra.Response {
	guid := ctx.URLParam("guid")
	userId := ctx.Values().GetString("user_id")
	if guid != "" {
		dag, err := c.Instance.GetGraphJaeger(guid, userId)
		if err != nil {
			return infra.ResponseReqErr(err, nil)
		}
		return infra.ResponseOK(dag)
	} else {
		dag, err := c.Instance.GetGraphJaegerAll(userId)
		if err != nil {
			return infra.ResponseReqErr(err, nil)
		}
		return infra.ResponseOK(dag)
	}
}

// Create serves
// Method:   GET
// Resource: http://localhost:8080/apis/instance/dag/update
func (c *Instance) GetDagUpdate(ctx iris.Context) *infra.Response {
	userId := ctx.Values().GetString("user_id")
	err := c.Instance.UpdateGraphJaeger(userId)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(nil)
}

// Create serves
// Method:   GET
// Resource: http://localhost:8080/apis/instance/report
func (c *Instance) GetReport(ctx iris.Context) *infra.Response {
	guid := ctx.URLParam("guid")
	contain := ctx.URLParam("container")
	//userId := ctx.Values().GetString("user_id")
	res, err := c.Instance.GetReport(guid, contain)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(res)
}

// Create serves
// Method:   GET
// Resource: http://localhost:8080/apis/instance/getfile
func (c *Instance) GetGetfile(ctx iris.Context) *infra.Response {
	guid := ctx.URLParam("guid")
	contain := ctx.URLParam("container")
	url := ctx.URLParam("url")
	userId := ctx.Values().GetString("user_id")
	res, err := c.Instance.GetFile(guid, contain, url, userId)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(res)
}

// Create serves
// Method:   GET
// Resource: http://localhost:8080/apis/instance/update/container
func (c *Instance) GetUpdateContainer(ctx iris.Context) *infra.Response {
	err := c.Instance.UpdateInstanceContainer()
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(nil)
}

// Create serves
// Method:   GET
// Resource: http://localhost:8080/apis/instance/jaeger/proxy
func (c *Instance) GetJaegerProxy(ctx iris.Context) *infra.Response {
	guid := ctx.URLParam("guid")
	data, err := c.Instance.GetJaegerProxy(guid)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(data)
}

//// Create serves
//// Method:   GET
//// Resource: http://localhost:8080/apis/instance/webssh
//func (c *Instance) GetWebssh(ctx iris.Context) *infra.Response {
//	id := ctx.Values().GetString("user_id")
//	admin, err := ctx.Values().GetBool("admin")
//	if err != nil {
//		return infra.ResponseReqErr(err, nil)
//	}
//	objs, err := c.Instance.GetWebSSH(admin, id, map[string]interface{}{})
//
//	if err != nil {
//		return infra.ResponseReqErr(err, nil)
//	}
//	return infra.ResponseOK(objs)
//}
